﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Text;

using FRL.DebtChased.Extensions;

namespace FRL.DebtChased.Repository.ViewModels
{

	/// <summary>
	/// Declaration of AuditModel class
	/// </summary>
	public class AuditModel
	{

		/////////////////////////////////////////////////////////////
		// Nested classes

		public class Element
		{

			/////////////////////////////////////////////////////////
			// Attributes

			internal int m_iUserActionId;
			public int UserActionId
			{
				get { return m_iUserActionId; }
			}

			internal int m_iPrimaryKey;
			public int PrimaryKey
			{
				get { return m_iPrimaryKey; }
			}

			internal string m_strTableName;
			public string TableName
			{
				get { return m_strTableName; }
			}

			public string RecordType
			{
				get 
				{
#if DEBUG
					Debug.Assert(m_strTableName.StartsWith("tb"));
#endif // #if DEBUG
					StringBuilder sb = new StringBuilder();
					for (int i1 = 2; i1 < m_strTableName.Length; i1++)
					{
						char c1 = m_strTableName[i1];
						if ((i1 > 2) && (char.IsUpper(c1)))
							sb.Append(" ");
						sb.Append(c1);
					}
					return sb.ToString(); 
				}
			}

			internal string m_strRecordName;
			public string RecordName
			{
				get { return m_strRecordName; }
			}

			internal string m_strChangesSummary;
			public string ChangesSummary
			{
				get { return m_strChangesSummary; }
			}

			internal UserAction.eActionType m_action;
			public UserAction.eActionType Action
			{
				get { return m_action; }
			}
			public string ActionAsText
			{
				get { return m_action.ToString(); }
			}

			internal DateTime m_dtTimestamp;
			public DateTime Timestamp
			{
				get { return m_dtTimestamp; }
			}

			internal string m_strFullName;
			public string FullName
			{
				get { return m_strFullName; }
			}

			internal List<Element> m_children = new List<Element>();
			public List<Element> Children
			{
				get { return m_children; }
			}

			public string AtAndByText
			{
				get 
				{
					return string.Format("{0} by {1}",
						m_dtTimestamp.ToCuteString(),
						m_strFullName
					);
				}
			}

			public string ActionTypeNameAsText
			{
				get
				{
					StringBuilder sb = new StringBuilder();
					if (m_action == UserAction.eActionType.Insert)
						sb.AppendFormat("Inserted");
					else
						sb.AppendFormat("{0}d", m_action);
					sb.AppendFormat(" {0} \"{1}\"", RecordType, this.m_strRecordName);
					return sb.ToString();					
				}
			}

		}

		/////////////////////////////////////////////////////////////
		// Attributes

		private List<Element> m_elements = new List<Element>();
		public List<Element> Elements
		{
			get { return m_elements; }
		}

		/////////////////////////////////////////////////////////////
		// Construction

		public AuditModel( DebtChasedEntities ent, string strFilterSearch, int iFilterUserId )
		{

			// Load the audit
			int? iFilterUserId2 = iFilterUserId == 0 ? default(int?) : iFilterUserId;
			var results = ent.AuditProc(strFilterSearch, iFilterUserId2);

			// Loop through results
			Element currentElement = null;
			foreach (var result in results)
			{

				// Create new element
				Element el = new Element()
				{
					m_iUserActionId = result.fdUserActionId,
					m_iPrimaryKey = result.fdPrimaryKey,
					m_strTableName = result.fdTableName,
					m_strRecordName = result.fdRecordName,
					m_strChangesSummary = result.fdChangesSummary,
					m_action = (UserAction.eActionType)result.fdAction,
					m_dtTimestamp = result.fdTimestamp,
					m_strFullName = result.fdFullName
				};

				// If this is a parent...
				if (result.fdIsParent)
				{

					// Add new parent
					m_elements.Add(el);
					currentElement = el;

				}
				else
				{

					// Add to current parent
					if (currentElement != null)
						currentElement.Children.Add(el);
#if DEBUG
					else
						Debug.Assert(false);
#endif // #if DEBUG

				}

			}

		}

	}

}
